﻿#include "pch.h"
namespace fs = std::filesystem;

#ifdef _WIN32
#define TEST_DATA_PATH "D:\\Work\\Bridge6\\test_data\\"
#else
#define TEST_DATA_PATH "/root/work/Bridge6/test_data/"
#endif

#define TEST_FILE(fname) (std::string(TEST_DATA_PATH) + fname).c_str()

// 采用测试前置条件：GC设置采用方法时长2分钟。
class AnalysisTest2 : public ::testing::Test
{
protected:
    void SetUp() override
    {
        std::cout << "SetUp" << std::endl;
        // 创建测试用的OrgFile句柄
        testHandle = createOrgFile("sampling_test");
        pChannelSampling = getChannelSamplingPtr();
        ASSERT_GT(testHandle, 0);

        // 预设谱图信息
        TOrgHead orgHead;
        EXPECT_TRUE(getOrgHead(testHandle, &orgHead));
        orgHead.Sample[0].Minutes = orgHead.Sample[1].Minutes = 200; // 采样时长2分钟，120秒
        orgHead.Detector = 0x0001ffff;
        orgHead.Frequency = 20;
        EXPECT_TRUE(setOrgHead(testHandle, &orgHead));

        // 初始化采样配置
        initBridgeAnalysis("config.ini");
    }

    void TearDown() override
    {
        std::cout << "TearDown" << std::endl;
        if (testHandle > 0)
        {
            closeOrgFile(testHandle);
        }
        if (fs::exists("saved.method"))
        {
            fs::remove("saved.method");
        }
        if (fs::exists("saved.org"))
        {
            fs::remove("saved.org");
        }
    }

    int64_t testHandle = -1;
    TChannelSampling *pChannelSampling = nullptr;
};

// 测试用例2：谱图方法综合测试一，加载方法和谱图。
TEST_F(AnalysisTest2, OrgMethodLoadFileTest)
{

    struct xxx
    {
        int32_t Identifier;    // 标识符
        int32_t Version;       // 版本号
        char Name[B64];        // 名称
        char GUID[B64];        // 全球唯一标识
        char ProjectID[B64];   // 项目ID
        char ProjectName[B64]; // 项目名称
        int32_t CreateTime;    // 创建时间
        int32_t UpdateTime;    // 更新时间
        char RelatedID[B64];   // 相关ID
        char Note[B128];       // 备注
        TEPara EPara;          // 计算参数
        TIPara IPara;          // 积分参数
        TDLLMETRIC metric;     // 标样用量
        AUTOIPARA autoIPara;   // 自动参数

        TUkPkFactor UkPkFactor[C4]; // 品控因子
    };
    int size = sizeof(xxx);
    std::cout << "size=" << size << std::endl;
    int64_t methodHandle = openMethodFile(TEST_FILE("saved.method"));
    EXPECT_GT(methodHandle, 0);
    std::unique_ptr<TMethodHead> methodHead = std::make_unique<TMethodHead>();
    std::unique_ptr<TCompList[]> compList = std::make_unique<TCompList[]>(4);
    int32_t nCompListCount = 0;
    ASSERT_TRUE(getMethodHead(methodHandle, METHOD_HANDLE, methodHead.get()));
    ASSERT_TRUE(getMethodCompList(methodHandle, METHOD_HANDLE, compList.get(), 4, &nCompListCount));
    EXPECT_EQ(nCompListCount, 4);
    EXPECT_EQ(methodHead.get()->IPara.testPkWidth, (float)0.03);
    EXPECT_EQ(methodHead.get()->IPara.autoNegative, 1);
    EXPECT_EQ(methodHead.get()->IPara.drift, (float)0);
#ifdef _WIN32    
    EXPECT_STREQ(compList.get()[0].Name, "总烃");
    EXPECT_STREQ(compList.get()[1].Name, "甲烷");
    EXPECT_STREQ(compList.get()[2].Name, "总烃");
    EXPECT_STREQ(compList.get()[3].Name, "甲烷");
#else
    EXPECT_STREQ(UTF8(compList.get()[0].Name).c_str(), "总烃");
    EXPECT_STREQ(UTF8(compList.get()[1].Name).c_str(), "甲烷");
    EXPECT_STREQ(UTF8(compList.get()[2].Name).c_str(), "总烃");
    EXPECT_STREQ(UTF8(compList.get()[3].Name).c_str(), "甲烷");
#endif
    int64_t orgHandle = openOrgFile(TEST_FILE("saved.org"));
    EXPECT_GT(orgHandle, 0);
    std::unique_ptr<TOrgHead> orgHead = std::make_unique<TOrgHead>();
    ASSERT_TRUE(getOrgHead(orgHandle, orgHead.get()));
    EXPECT_EQ(orgHead.get()->Detector, 0x0001ffff);
    EXPECT_EQ(orgHead.get()->Frequency, 20);
    std::unique_ptr<TMethodHead> methodHead1 = std::make_unique<TMethodHead>();
    std::unique_ptr<TCompList[]> compList1 = std::make_unique<TCompList[]>(4);
    int32_t nCompListCount1 = 0;
    ASSERT_TRUE(getMethodHead(orgHandle, ORG_HANDLE, methodHead1.get()));
    ASSERT_TRUE(getMethodCompList(orgHandle, ORG_HANDLE, compList1.get(), 4, &nCompListCount1));
    EXPECT_EQ(nCompListCount1, 4);
    EXPECT_EQ(methodHead1.get()->IPara.testPkWidth, (float)0.03);
    EXPECT_EQ(methodHead1.get()->IPara.autoNegative, (float)1);
    EXPECT_EQ(methodHead1.get()->IPara.drift, (float)0);
#ifdef _WIN32
    EXPECT_STREQ(compList1.get()[0].Name, "甲烷");
    EXPECT_STREQ(compList1.get()[1].Name, "总烃");
    EXPECT_STREQ(compList1.get()[2].Name, "甲烷");
    EXPECT_STREQ(compList1.get()[3].Name, "总烃");
#else
    EXPECT_STREQ(UTF8(compList1.get()[0].Name).c_str(), "甲烷");
    EXPECT_STREQ(UTF8(compList1.get()[1].Name).c_str(), "总烃");
    EXPECT_STREQ(UTF8(compList1.get()[2].Name).c_str(), "甲烷");
    EXPECT_STREQ(UTF8(compList1.get()[3].Name).c_str(), "总烃");
#endif    

    closeMethodFile(methodHandle);
    closeOrgFile(orgHandle);
}

// 测试用例3：谱图积分测试：用谱图内方法积分。
TEST_F(AnalysisTest2, AnalysisUsingInnerMethodTest)
{
    int64_t orgHandle = openOrgFile(TEST_FILE("saved.org"));
    EXPECT_GT(orgHandle, 0);
    EXPECT_TRUE(analysis(orgHandle, -1));

    int32_t rowCount = 0;
    std::unique_ptr<TAnalResult[]> analResultList = std::make_unique<TAnalResult[]>(100);
    EXPECT_TRUE(getOrgAnalResult(orgHandle, 0, analResultList.get(), 100, &rowCount));
    EXPECT_EQ(rowCount, 4);
#ifdef _WIN32
    EXPECT_STREQ(analResultList.get()[0].Name, "甲烷");
    EXPECT_STREQ(analResultList.get()[1].Name, "总烃");
#else
    EXPECT_STREQ(UTF8(analResultList.get()[0].Name).c_str(), "甲烷");
    EXPECT_STREQ(UTF8(analResultList.get()[1].Name).c_str(), "总烃");
#endif    
    EXPECT_NEAR(analResultList.get()[0].Conc, 20, 0.01);
    EXPECT_NEAR(analResultList.get()[1].Conc, 10, 0.01);

    closeOrgFile(orgHandle);
}

// 测试用例4：谱图积分测试：用谱图外部方法积分。
TEST_F(AnalysisTest2, AnalysisUsingOtherMethodTest)
{
    int64_t methodHandle = openMethodFile(TEST_FILE("saved.method"));
    EXPECT_GT(methodHandle, 0);
    int64_t orgHandle = openOrgFile(TEST_FILE("saved.org"));
    EXPECT_GT(orgHandle, 0);
    EXPECT_TRUE(analysis(orgHandle, methodHandle));

    int32_t rowCount = 0;
    std::unique_ptr<TAnalResult[]> analResultList = std::make_unique<TAnalResult[]>(100);
    EXPECT_TRUE(getOrgAnalResult(orgHandle, 0, analResultList.get(), 100, &rowCount));
    EXPECT_EQ(rowCount, 4);
#ifdef _WIN32    
    EXPECT_STREQ(analResultList.get()[1].Name, "甲烷");
    EXPECT_STREQ(analResultList.get()[0].Name, "总烃");
#else
    EXPECT_STREQ(UTF8(analResultList.get()[1].Name).c_str(), "甲烷");
    EXPECT_STREQ(UTF8(analResultList.get()[0].Name).c_str(), "总烃");
#endif    
    EXPECT_NEAR(analResultList.get()[0].Conc, 20, 0.01);
    EXPECT_NEAR(analResultList.get()[1].Conc, 10, 0.01);

    closeMethodFile(methodHandle);
    closeOrgFile(orgHandle);
}

#ifdef TEST_SAMPLING
int32_t main(int32_t argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
#endif